home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part1 / 7768 < prev    next >
Encoding:
Text File  |  1996-08-05  |  12.5 KB  |  413 lines

  1. Path: li.net!usenet
  2. From: aholder@li.net (Andrew Holder)
  3. Newsgroups: comp.lang.basic.misc,comp.lang.c
  4. Subject: Re: Uuencode source code requested
  5. Date: 28 Feb 1996 20:52:36 GMT
  6. Organization: Weenies Inc.
  7. Message-ID: <4h2fak$4te@linet06.li.net>
  8. References: <4gquoe$3tr@mozo.cc.purdue.edu>
  9. NNTP-Posting-Host: lisuser61.li.net
  10. Mime-Version: 1.0
  11. Content-Type: Text/Plain; charset=ISO-8859-1
  12. X-Newsreader: WinVN 0.99.5
  13.  
  14. In article <4gquoe$3tr@mozo.cc.purdue.edu>, sksinha@expert.cc.purdue.edu 
  15. says...
  16. >
  17. >
  18. >hi,
  19. >
  20. >i would greatly appreciate if someone could post/email me the
  21. >source code for uuencode (either in basic or c). I assume that
  22. >the source for this program is not copyrighted!
  23. >
  24. >Thank you,
  25. >
  26. >Sinha
  27. >
  28. >--------------------------------------------------------------------------
  29. >**************************************************************************
  30. >Suvinay Sinha             ||||           ||||           
  31. >3175, CIVL                ||||  *    *   ||||  Sarcasm is the lowest 
  32. >Ph : (317) 494-0274 (Lab) ||||     |     ||||  form of humour.         
  33. >     (317) 494-0754 (Off) ||||    \_/    ||||  
  34. >     (317) 743-7091 (Hom) ||||           ||||  
  35. >**************************************************************************
  36. >            Department of Earth & Atm Scis., Purdue University,   
  37. >-------------------------------------------------------------------------- 
  38. >
  39. >
  40. >-- 
  41. >--------------------------------------------------------------------------
  42. >**************************************************************************
  43. >Suvinay Sinha             ||||           ||||           
  44. >3175, CIVL                ||||  *    *   ||||  Sarcasm is the lowest 
  45.  
  46.  
  47. /*uudoall.c cleans up split files checks checksums and writes by h**2 7/4/91
  48.  *  (c) 1991 by Howard Helman
  49.  */
  50.  
  51.  
  52.  
  53. /*
  54.   uudoall.c can usually handle the split files with all the intervening mail
  55.   crap.
  56.   Automatically checks for checksums on lines and automatically checks for
  57.   a `size' line at the end and verifies the size.  It also computes the sum
  58.   value for the decoded file. I could not find any convention on people using
  59.   sum so the program just computes it and prints it.
  60.  
  61.   Compile by defining DOS for msdos use or OS2 for GCC on OS/2 or UNIX for 
  62. use elsewhere.
  63.  */
  64.  
  65.  
  66. /* the program is called by :
  67.         uudoall [opts] -ddir infile [...]
  68.  where opts are:
  69.                 -s+             do size check
  70.                 -s-             inhibit size check
  71.                 -c+             do line by line checksum
  72.                 -c-             inhibit checksum
  73.                 -ddir   place output files in the named directory
  74.                 infile  the file to process (all parts should be 
  75. concatenated.)
  76.                 [...]   options and file names may be repeated.
  77.                                 The last option setting is in effect when a 
  78. file is
  79.                                 processed.
  80.  If the program cannot open the output file, it prompts the user
  81.  for a new file name or `enter' to stop.
  82.  The trimming of trailing blanks is handled properly.  This program
  83.  has been in use continually and has only had one problem: a user
  84.  signature started in col 1 and had a `M' and over sixty characters in the
  85.  line.  This is what the program searches for to find the next part of the
  86.  encoded file.
  87. */
  88.  
  89. /*
  90.   This program is donated to the public domain provided that the source
  91.   is distributed in total and my authorship of the program is credited.
  92.  
  93.                 Howard Helman
  94.                 Box 340
  95.                 Manhattan Beach
  96.                 CA 90266
  97. */
  98.  
  99. /* v1.1, 3 Oct 91   Toad Hall Tweak
  100.  * - Slight tweaks to reduce Turbo C v2.0 warnings.
  101.  * - Threw in some prototypes.
  102.  * - Reformatted to K&R standards (via good old Mister Mangler,
  103.  *   AKA indent).
  104.  * David Kirschbaum
  105.  * Toad Hall
  106.  * kirsch@usasoc.soc.mil
  107.  */
  108.  
  109. /* Added #ifdef's for OS/2 August 29, 1993 */
  110.  
  111. #ifdef __TURBOC__
  112. #define DOS 1
  113. #endif
  114.  
  115. #ifdef DOS
  116. #include <stdlib.h>
  117. #include <alloc.h>
  118. #define ReaD "rt"
  119. #define WritE "wb"
  120. #define SlasH "\\"
  121. #endif
  122. #ifdef UNIX
  123. #define ReaD "r"
  124. #define WritE "w"
  125. #define SlasH "/"
  126. #endif
  127. #ifdef OS2
  128. #define ReaD "rt"
  129. #define WritE "wb"
  130. #define SlasH "/"
  131. #endif
  132.  
  133. #include <stdio.h>
  134. #include <string.h>
  135. #include <ctype.h>
  136.  
  137. #define Bsize 80
  138. #define SUMSIZE 64
  139. #define DEC(c)  (((x_x=(c))>=' ')?((x_x-' ')&077):(0))  /* single char decode 
  140. */
  141. #define match(x) matcher(buf,x)
  142.  
  143. static int dosize = 1, docheck = 1;
  144. static char x_x, dir[80];
  145. static long nbytes;
  146. static unsigned int sum1;
  147.  
  148. #ifdef DOS
  149. static void *vbi;
  150. static unsigned bn;
  151. #endif
  152.  
  153. #ifdef __TURBOC__
  154. /* v1.1 I like prototypes */
  155. int matcher(char *a, char *b);
  156. int hget(char *buf, int bs, FILE *in);
  157. void decode(FILE *in, FILE *out, char *dest);
  158. void doopts(char *s);
  159. void decodeit(FILE *in, char buf[Bsize]);
  160.  
  161. #endif
  162. enum States {
  163.         BeginSearch, InBody, GapOrEnd, LookEnd, PutTwo, PutEnd,
  164.         Mfind
  165. } state = BeginSearch;
  166.  
  167. int matcher(a, b)
  168. char *a, *b;
  169. {
  170.         while (*b && *a == *b)
  171.                 a++, b++;
  172.         return (!*b);
  173. }
  174.  
  175. int hget(buf, bs, in)
  176. char *buf;
  177. int bs;
  178. FILE *in;
  179. {
  180.         static char s1[Bsize], s2[Bsize];
  181.  
  182.         if (state == PutEnd) {
  183.                 strcpy(buf, "end");
  184.                 state = BeginSearch;
  185.                 return 1;
  186.         }
  187.         if (state == PutTwo) {
  188.                 strcpy(buf, s2);
  189.                 state = PutEnd;
  190.                 return 1;
  191.         }
  192.         while (fgets(buf, bs, in)) {
  193.                 switch (state) {
  194.                 case BeginSearch:
  195.                         if (match("begin "))
  196.                                 state = InBody;
  197.                         return 1;
  198.                 case InBody:
  199.                         if (*buf == 'M')
  200.                                 return 1;
  201.                         else if (*buf == '`') {
  202.                                 state = BeginSearch;
  203.                                 return 1;
  204.                         } else {
  205.                                 strcpy(s1, buf);
  206.                                 state = GapOrEnd;
  207.                         }
  208.                         break;
  209.                 case GapOrEnd:
  210.                         if (match("end")) {
  211.                                 strcpy(buf, s1);
  212.                                 state = PutEnd;
  213.                                 return 1;
  214.                         } else {
  215.                                 strcpy(s2, buf);
  216.                                 state = LookEnd;
  217.                         }
  218.                         break;
  219.                 case LookEnd:
  220.                         if (match("end")) {
  221.                                 strcpy(buf, s1);
  222.                                 state = PutTwo;
  223.                                 return 1;
  224.                         } else
  225.                                 state = Mfind;
  226.                         break;
  227.                 case Mfind:
  228.                         if (*buf == 'M' && strlen(buf) > 60) {
  229.                                 state = InBody;
  230.                                 return 1;
  231.                         }
  232.                         break;
  233.                 }
  234.         }
  235.         return 0;
  236. }
  237.  
  238. void decode(in, out, dest)
  239. FILE *in, *out;
  240. char *dest;
  241. {
  242.         int j, n, checksum, altsum;
  243.         char buf[Bsize], *bp, hold[Bsize / 4 * 3], *jp;
  244.         unsigned pcline = 0, line = 0;
  245.  
  246.         sum1 = 0;
  247.         nbytes = 0;
  248.         while (memset(buf, 0, Bsize), hget(buf, Bsize, in)
  249.           &&(n = DEC(*buf)) > 0) {
  250.                 line++;
  251.                 altsum = checksum = 0;
  252.                 bp = buf + 1;
  253.                 for (jp = hold, j = n; j > 0; j -= 3, bp += 4) {
  254.                         *jp = (DEC(bp[0]) << 2) | (DEC(bp[1]) >> 4);
  255.                         checksum += *jp++;
  256.                         *jp = (DEC(bp[1]) << 4) | (DEC(bp[2]) >> 2);
  257.                         checksum += *jp++;
  258.                         *jp = (DEC(bp[2]) << 6) | (DEC(bp[3]));
  259.                         checksum += *jp++;
  260.                         altsum += bp[0] + bp[1] + bp[2] + bp[3];
  261.                 }
  262.                 for (j = 0, jp = hold; j < n; j++, jp++)
  263.                         sum1 = ((sum1 >> 1) + ((sum1 & 1) ? 0x8000 : 0)
  264.                                 + (*jp & 0xff)) & 0xffff;
  265.                 nbytes += n;
  266.                 if (fwrite(hold, 1, n, out) != n) {
  267.                         fprintf(stderr, "ERROR: error writing to %s\n", 
  268. dest);
  269.                         exit(1);
  270.                 }
  271.                 if (!isspace(*bp) && docheck)
  272.                         if ((checksum & (SUMSIZE - 1)) != DEC(*bp)
  273.                           && (altsum & 077) != (DEC(*bp) & 077)) {
  274.                                 if (!pcline)
  275.                                         pcline = line;
  276.                         } else if (pcline) {
  277.                                 fprintf(stderr,
  278.                                                 "ERROR:Bad Checksum lines 
  279. %u-%u\n", pcline, line);
  280.                                 pcline = 0;
  281.                         }
  282.         }
  283.         if (pcline)
  284.                 fprintf(stderr, "ERROR:Bad Checksum lines %u-%u\n", pcline, 
  285. line);
  286.         if (feof(in) ||ferror(in)) {
  287.                 fprintf(stderr, "ERROR: Input ended unexpectedly!\n");
  288.                 exit(1);
  289.         }
  290. }
  291.  
  292. void decodeit(in, buf)
  293. FILE *in;
  294. char buf[Bsize];
  295. {
  296.         int mode;
  297.         long filesize, tsize;
  298.         FILE *out;
  299.         char fname[128], dest[128];
  300.  
  301.         sscanf(buf, "begin %o %s", &mode, dest);
  302.         while (strcpy(fname, dir) && strcat(fname, dest)
  303.           && !(out = fopen(fname, WritE))) {
  304.                 fprintf(stderr, "ERROR: Can't open output file %s\nTry new 
  305. one:",
  306.                                 fname);
  307.                 gets(dest);
  308.                 if (!*dest)
  309.                         exit(1);
  310.         }
  311. #ifdef DOS
  312.         setvbuf(out, (char *) vbi + bn * 512, _IOFBF, bn * 512);
  313. #endif
  314.         fprintf(stderr, "Creating %s\n", fname);
  315.         decode(in, out, dest);
  316.         if (!hget(buf, Bsize, in) ||!match("end")) {
  317.                 fprintf(stderr, "ERROR: no `end' line\n");
  318.                 exit(1);
  319.         }
  320.         tsize = ftell(out);
  321.         if (dosize && hget(buf, Bsize, in) &&match("size ")) {
  322.                 sscanf(buf, "size %ld", &filesize);
  323.                 if (tsize != filesize) {
  324.                         fprintf(stderr,
  325.                         "ERROR: file should have been %ld bytes long but was 
  326. %ld.\n",
  327.                                         filesize, tsize);
  328.                         exit(1);
  329.                 }
  330.         } else if (dosize)
  331.                 fprintf(stderr, "Size check not done\n");
  332.         if (tsize != nbytes) {
  333.                 fprintf(stderr, "Size Error:file=%ld data=%ld\n", tsize, 
  334. nbytes);
  335.                 exit(1);
  336.         }
  337.         fprintf(stderr, "sums: %u %ld %ld\n", sum1, (nbytes + 1023) / 1024,
  338.                         nbytes);
  339.         fclose(out);
  340. }
  341.  
  342. void doopts(s)
  343. char *s;
  344. {
  345.         if (s[1] == 's')
  346.                 dosize = s[2] != '-';
  347.         else if (s[1] == 'c')
  348.                 docheck = s[2] != '-';
  349.         else if (s[1] == 'd') {
  350.                 strcpy(dir, s + 2);
  351.                 if (*dir)
  352.                         strcat(dir, SlasH);
  353.         } else {
  354.                 fprintf(stderr, "Illegal flag %s\n", s);
  355.                 exit(1);
  356.         }
  357. }
  358.  
  359. int main(argc, argv)
  360. int argc;
  361. char **argv;
  362. {
  363.         FILE *in;
  364.         int nf = 0, i;
  365.         char buf[80];
  366.  
  367.         *dir = 0;
  368.         if (argc < 2) {
  369.                 fprintf(stderr,
  370.         "UUDOALL is a UUDECODER for multiple part uuencoded files that have 
  371. been placed\n");
  372.                 fprintf(stderr,
  373.         "in a single file. For example, all of the articles from a USENET 
  374. newsgroup\n");
  375.                 fprintf(stderr,
  376.         "could be saved to a single file.  UUDOALL would automatically 
  377. extract any\n");
  378.                 fprintf(stderr,
  379.         "complete UUENCODED files.  It will handle UNIX and OS/2 long 
  380. filenames.\n\n");
  381.                 fprintf(stderr,
  382.         "USAGE: uudoall [opts] -ddir infile [...] where opts are -s+|- 
  383. -c+|-\n");
  384.                 exit(1);
  385.         }
  386. #ifdef DOS
  387.         bn = coreleft() / 1024 - 2;
  388.         vbi = malloc(512 * 2 * bn);
  389. #endif
  390.         for (i = 1; i < argc; i++) {
  391.                 if (argv[i][0] == '-')
  392.                         doopts(argv[i]);
  393.                 else if (!(in = fopen(argv[i], ReaD)))
  394.                         fprintf(stderr, "ERROR: can't find %s\n", argv[i]);
  395.                 else {
  396. #ifdef DOS
  397.                         setvbuf(in, vbi, _IOFBF, bn * 512);
  398. #endif
  399.                         while (hget(buf, Bsize, in)) {
  400.                                 if (match("begin ")) {
  401.                                         nf++;
  402.                                         decodeit(in, buf);
  403.                                 }
  404.                         }
  405.                         fclose(in);
  406.                 }
  407.         }
  408.         return !nf;
  409. }
  410.  
  411.  
  412.  
  413.